package com.bball.court;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Application;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.bball.court.controller.CourtController;
import com.bball.court.controller.PlayerController;
import com.bball.court.controller.parse.ParseCourtController;
import com.bball.court.controller.parse.ParsePlayerController;
import com.bball.court.data.FacDatabaseHelper;
import com.bball.court.model.parse.ParseCourt;
import com.bball.court.receiver.LocationBroadcastReceiver;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.parse.Parse;
import com.parse.ParseFacebookUtils;
import com.parse.ParseObject;

public class FaCApplication extends Application {

    private static final String FACEBOOK_APP_ID = "1392775207628343";
    private static final String CLIENT_KEY = "NaBMEGW8KLwkaIFhzABiRJOzFYhpq7JZakj4heKc";
    private static final String APP_ID = "u5ku5ZMBw0KtOQRXv3xU82WU5GgEx9v8C5mLThkH";
    public static final String VOLLEY = "VOLLEY";
    // public static final String IMAGE_LOADER = "IMAGE_LOADER";
    public static final String LOCATION_CLIENT = "LOCATION_CLIENT";
    public static final String COURT_CONTROLLER = "COURT_CONTROLLER";
    public static final String GSON = "GSON";
    public static final String PLAYER_CONTROLLER = "PLAYER_CONTROLLER";

    private RequestQueue requestQueue;
    // private Picasso imageLoader;
    private LocationClient locationClient;
    private CourtController courtController;
    private PlayerController playerController;

    // private Gson gson;

    private enum BackendType {
        PLAY, GOOGLE, PARSE
    }

    private BackendType backendType = BackendType.PARSE;

    @Override
    public void onCreate() {
        super.onCreate();
        FacDatabaseHelper.init(this);
        // imageLoader = Picasso.with(this);
        // imageLoader.setDebugging(true);
        requestQueue = Volley.newRequestQueue(getApplicationContext());
        if (backendType == BackendType.PARSE) {
            ParseObject.registerSubclass(ParseCourt.class);
            Parse.initialize(this, APP_ID, CLIENT_KEY);
            ParseFacebookUtils.initialize(FACEBOOK_APP_ID);
        }
        int googlePlayServicesAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
        if (ConnectionResult.SUCCESS == googlePlayServicesAvailable) {
            locationClient = new LocationClient(getApplicationContext(), connectionCallbacks, onConnectionFailedListener);
            locationClient.connect();
        }
        AccountManager accountManager = AccountManager.get(this);
        Account[] accountsByType = accountManager.getAccountsByType("com.google");
        if (accountsByType.length > 0) {
            Account account = accountsByType[0];
            PreferenceHelper.saveLogin(this, account.name);
            Log.i(getClass().getSimpleName(), "Login retrieved : " + PreferenceHelper.getLogin(this));
        }
        courtController = getCourtController();
        playerController = getPlayerController();
        // gson = getGson();
    }

    /*
     * private Gson getGson() { switch (backendType) { case PLAY: return new
     * GsonBuilder().registerTypeAdapter(Court.class, new PlayCourtInstanceCreator())
     * .registerTypeAdapter(CourtList.class, new PlayCourtListInstanceCreator()).create(); default: return new
     * GsonBuilder().registerTypeAdapter(Court.class, new GoogleCourtInstanceCreator())
     * .registerTypeAdapter(CourtList.class, new GoogleCourtListInstanceCreator()).create(); } }
     */

    private CourtController getCourtController() {
        switch (backendType) {
        case PLAY:
            return null; // new PlayCourtController(getApplicationContext());
        case PARSE:
            return new ParseCourtController(this);
        default:
            return null; // new GoogleCourtController(getApplicationContext());
        }
    }

    private PlayerController getPlayerController() {
        switch (backendType) {
        case PLAY:
            return null;// new PlayPlayerController(getApplicationContext());
        case PARSE:
            return new ParsePlayerController();
        default:
            return null;// new GooglePlayerController(getApplicationContext());
        }
    }

    private GooglePlayServicesClient.ConnectionCallbacks connectionCallbacks = new GooglePlayServicesClient.ConnectionCallbacks() {
        @Override
        public void onConnected(Bundle bundle) {
            Log.i(getClass().getSimpleName(), "Connected at GooglePlayService");
            LocationRequest request = LocationRequest.create();
            request.setInterval(60000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            Log.i(getClass().getSimpleName(), "Trying to locate user");
            locationClient.requestLocationUpdates(request, onLocationChangeListener);
        }

        @Override
        public void onDisconnected() {
            Log.i(getClass().getSimpleName(), "Disconnected at GooglePlayService");
        }
    };

    private GooglePlayServicesClient.OnConnectionFailedListener onConnectionFailedListener = new GooglePlayServicesClient.OnConnectionFailedListener() {
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            Log.i(getClass().getSimpleName(), "Connection failed at GooglePlayService");
        }
    };

    private LocationListener onLocationChangeListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Log.i(getClass().getSimpleName(), "User Located lat " + location.getLatitude() + " lng " + location.getLongitude());
            sendBroadcast(LocationBroadcastReceiver.newIntent(location));
        }
    };

    @Override
    public Object getSystemService(String name) {
        if (VOLLEY.equals(name)) {
            return this.requestQueue;
            /*
             * } else if (IMAGE_LOADER.equals(name)) { return this.imageLoader;
             */
        } else if (LOCATION_CLIENT.equals(name)) {
            return locationClient;
        } else if (COURT_CONTROLLER.equals(name)) {
            return courtController;
        } else if (PLAYER_CONTROLLER.equals(name)) {
            return playerController;
        } /*
           * else if (GSON.equals(name)) { return gson; }
           */
        return super.getSystemService(name);
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        FacDatabaseHelper.getInstance(this).close();
    }

    public BackendType getBackendType() {
        return backendType;
    }

}
